#include"../include/main_header.h"
#include"../include/block.h"
#include"../include/free_list.h"
#include<stdlib.h>

void initialize_free_list()
{
	unsigned long int i;
	fl.first_free = 0;
	fl.list=(unsigned long int *)malloc(FREE_LIST_SIZE);
	for(i=0; i<(FREE_LIST_SIZE)/sizeof(unsigned long int); i++)
	{
		fl.list[i] = 0;
	}
}
void create_free_list()
{
	struct block b;
	unsigned long int blocks,i;
//	fl.list=(unsigned long int *)malloc(FREE_LIST_SIZE);
	fl.first_free=(m.free_address-sizeof(struct main_header))/BLOCK_SIZE;

	blocks=(FREE_LIST_SIZE)/(sizeof(unsigned long int));
	//printf("freelist size is:%ld and first free address is %ld and original:%ld",blocks,fl.first_free,m.free_address);

	fseek(fp,sizeof(struct main_header),0);
//	printf("%ld  %ld",FREE_LIST_SIZE, blocks);

	
	for(i=0;i<blocks;i++)
	{
		fread(&b,sizeof(struct block),1,fp);
		//printf("%s\n", "I am here3");
		if(b.next!=0xFFFF)
		{
	
			fl.list[i]=(b.next-sizeof(struct main_header))/BLOCK_SIZE;
		}
		else
		{
			fl.list[i]=b.next;
		}
		//printf("\n%ld\n",fl.list[i]);
	}
	//fl.list[blocks]=0xFFFF;

}




unsigned long int get_free_block_new()//returns absolute address
{

unsigned long int temp;
//save the address of first free block in temp in which the file will be stored
temp=fl.first_free;
fl.first_free=fl.list[fl.first_free];
fl.list[temp]=0xFFFF;

temp=temp*BLOCK_SIZE + sizeof(struct main_header);
return temp;



}
unsigned long int absoluteToblock(unsigned long int address)
{
return ((address-sizeof(struct main_header))/BLOCK_SIZE);
}

unsigned long int blockToabsolute(unsigned long int address)
{
return (address*BLOCK_SIZE + sizeof(struct main_header));
}

void free_data_blocks(unsigned long int startblock)
{
	unsigned long int temp;
	int i;
	temp = fl.first_free;
	fl.first_free = startblock;
	//printf("\n------before free------\nstart block:%ld\nfirst free:%ld\n",startblock,temp );
	
	/*for(i=0;i<10;i++)
	{
		printf("\nblocks:%ld",fl.list[i]);
	}*/
	
	while(fl.list[startblock]!=0xFFFF)
	{
		startblock = fl.list[startblock];
	//	printf("\nblocks:%ld",startblock);
	}
	//printf("\n------after free------\nlast block freed:%ld\nfirst free:%ld\n",startblock,fl.first_free);
	fl.list[startblock] = temp;
	/*for(i=0;i<10;i++)
	{
		printf("\nblocks:%ld",fl.list[i]);
	}*/
}

unsigned long int get_secondlastblock(unsigned long int startblock)
{
	unsigned long int secondlast;
	secondlast = startblock;
	while(fl.list[startblock]!=0xFFFF)
	{
		//printf("\ninside loop\n");
		secondlast = startblock;
		startblock = fl.list[startblock];
	}
	//printf("\nsecond last%ld\n",secondlast);
	return secondlast;
}
void free_dir_blocks(unsigned long int secondlast)
{	
	int i;
//	printf("\nsecondlast is :%ld\n",secondlast);
	unsigned long int startblock;	
	if(fl.list[secondlast]==0xFFFF)
	{
		free_data_blocks(secondlast);
		return;
	}
	else
	{	
		startblock = fl.list[secondlast];
//		printf("\nlast is : %ld",fl.list[secondlast]);
		free_data_blocks(startblock);
		fl.list[secondlast] = 0xFFFF;
//		printf("\nafter updation second last is : %ld",fl.list[secondlast]);
	}
//printf("\n-----------after final updation------------------\nfirst free:%ld\n",fl.first_free);
/*	for(i=0;i<10;i++)
	{
		printf("\nblocks:%ld",fl.list[i]);
	}*/

}

void display_blocks_info()
{
	int i;
	printf("------------------Blocks Info------------------------\n");
	printf("\nfirst free address :%ld\n", fl.first_free);
	for(i=0;i<10;i++)
	{
		printf("\nblocks:%ld",fl.list[i]);
	}	
	printf("-----------------------------------------------------\n");


}

unsigned long int get_current_free_size()
{
	unsigned long int  count = 0,total_size,block;
	
	total_size = (FREE_LIST_SIZE)/(sizeof(unsigned long int));

	block = fl.first_free;
	while(fl.list[block]!=0xFFFF)
	{
		block = fl.list[block];
		count++; 
	}

	return count;

}
void define_free_list_size()
{
	
	FREE_LIST_SIZE = sizeof(unsigned long int)*((m.vfs_size-sizeof(struct main_header))/BLOCK_SIZE);
}